import allure
import pytest

from utils.assert_utils import AssertUtils
from utils.extract_var import ExtractUtil
from utils.handle_yaml import write_var
from utils.log_control import INFO
from utils.read_yaml import ReadYaml
from utils.request_util import send_all_request
from utils.yaml_verify import CaseInfo
from configs.data import GlobalVariable

variable = GlobalVariable()

r_yaml = ReadYaml()
eu = ExtractUtil()
ast = AssertUtils()


def case_flow(case_info: CaseInfo):
    # 0.allure报告
    allure.dynamic.id(case_info.id)  # 用例编号
    allure.dynamic.title(case_info.skip)  # 是否跳过 1跳过，0不跳过
    allure.dynamic.epic(case_info.epic)  # 添加用例属于哪个需求的
    allure.dynamic.feature(case_info.feature)  # 模块
    allure.dynamic.story(case_info.story)  # 接口
    allure.dynamic.title(case_info.title)  # 标题
    api_info = ("接口信息："+ str(case_info.id) + str(case_info.skip) + ">>" + str(case_info.epic) + ">>" + str(case_info.feature) +
                ">>" + str(case_info.story) + ">>" + str(case_info.title))
    INFO.logger.info(api_info)
    if case_info.skip:
        variable.skip_list.append('skip')
        write_var({'skip_list': variable.skip_list})
        pytest.skip("用例跳过")
    # 1.数据替换  request对应的数据先 进行替换一下
    old_data = case_info.request  # 原始的数据
    # 修改请求头
    old_data['headers'].update(r_yaml.get_value('reqConfig/headers'))
    # 2.调用替换的方法进行替换, 变成用来发送请求的数据
    new_data = eu.exchange_var(old_data)
    # 3.发送请求
    res = send_all_request(case_info,new_data)
    # 4.数据提取
    extract = case_info.extract  # [{},{}]
    if extract:  # 如果存在需要提取的内容，才会提取内容
        """
        [
            {昵称nickname: [ json,"$..nickname",0 ]},
            {token: [ text,'"token":"(.*?)"',0 ]}
        ]
        #   提取之后的变量:  [响应信息的什么属性里面进行提取，提取的表达式，下标]
        """
        for i in extract:
            for key, value in i.items():
                eu.extract_var(key, res, *value)
    # 5.断言
    valid = case_info.validate  # [{断言说明信息:[预期结果，实际结果]},{断言说明信息:[预期结果，实际结果]}]
    # 数据替换
    valid = eu.exchange_var(valid)
    # [{equals:xxx},{contains:xxx},xxx]
    ast.assert_all_cases(valid, res, api_info)


